package com.zhoug.aop.aspect;

import android.util.Log;
import android.view.View;


import com.zhoug.aop.R;
import com.zhoug.aop.annotation.ClickLimit;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;

/**全部单击事件,限制单击事件生效的时间间隔
 * @Author 35574
 * @Date 2020/6/30
 * @Description
 */
@Deprecated
//@Aspect
public class AllClickLimitAspect {
    private static final String TAG = ">>>ClickLimitAspect";
    private static final int CHECK_FOR_DEFAULT_TIME = 500;
    private static final String POINTCUT_ON_VIEW_CLICK  = "execution(* android.view.View.OnClickListener.onClick(..))";
    private static final int TAG_ID=4568134;

    //切入点
//    @Pointcut(POINTCUT_ON_VIEW_CLICK )
    public void onViewClick(){
    }

//    @Around("onViewClick()")
    public void processJoinPoint(ProceedingJoinPoint joinPoint) throws Throwable {
        Log.d(TAG, "-----method is click--- joinPoint="+joinPoint);//execution(void com.heking.aopmodule.MainActivity.1.onClick(View))
        try {
            Signature signature = joinPoint.getSignature();
            if (!(signature instanceof MethodSignature)){
                Log.e(TAG, "method is no MethodSignature, so proceed it");
                joinPoint.proceed();
                return;
            }

            MethodSignature methodSignature = (MethodSignature) signature;
            Method method = methodSignature.getMethod();
            Log.d(TAG, "processJoinPoint:method="+method);//public void com.heking.aopmodule.MainActivity$1.onClick(android.view.View)
            boolean isHasLimitAnnotation = method.isAnnotationPresent(ClickLimit.class);
            Log.d(TAG, "processJoinPoint:isHasLimitAnnotation="+isHasLimitAnnotation);
            String methodName = method.getName();
            int intervalTime = CHECK_FOR_DEFAULT_TIME;
            if (isHasLimitAnnotation){
                ClickLimit clickLimit = method.getAnnotation(ClickLimit.class);
                int limitTime = clickLimit.value();
                // not limit click
                if (limitTime <= 0){
                    Log.d(TAG, "method: " + methodName + " limitTime is zero, so proceed it");
                    joinPoint.proceed();
                    return;
                }
                intervalTime = limitTime;
                Log.d(TAG, "methodName " +  methodName + " intervalTime is " + intervalTime);
            }
            //方法参数
            Object[] args = joinPoint.getArgs();
            View view = getViewFromArgs(args);
            if (view == null) {
                Log.e(TAG, "view is null, proceed");
                joinPoint.proceed();
                return;
            }

            Object viewTimeTag =  view.getTag(TAG_ID);
            // first click viewTimeTag is null.
            //第一次点击事件,
            if (viewTimeTag == null){
                Log.d(TAG, "lastClickTime is zero , proceed");
                proceedAnSetTimeTag(joinPoint, view);
                return;
            }

            long lastClickTime = (long) viewTimeTag;
            if (lastClickTime <= 0){
                Log.d(TAG, "lastClickTime is zero , proceed");
                proceedAnSetTimeTag(joinPoint, view);
                return;
            }

            // in limit time
            if (!canClick(lastClickTime, intervalTime)){
                Log.e(TAG, "is in limit time , return");
                return;
            }
            proceedAnSetTimeTag(joinPoint, view);
            Log.d(TAG, "view proceed.");
        } catch (Throwable e) {
            e.printStackTrace();
            Log.d(TAG, e.getMessage());
            joinPoint.proceed();
        }
    }

    public void proceedAnSetTimeTag(ProceedingJoinPoint joinPoint, View view) throws Throwable {
        //设置当前调用的时间到View的Tag
        view.setTag(TAG_ID, System.currentTimeMillis());
        joinPoint.proceed();
    }


    /**
     * 获取 view 参数
     *
     * @param args
     * @return
     */
    public View getViewFromArgs(Object[] args) {
        if (args != null && args.length > 0) {
            Object arg = args[0];
            if (arg instanceof View) {
                return (View) arg;
            }
        }
        return null;
    }

    /**
     * 判断是否达到可以点击的时间间隔
     * @param lastClickTime
     * @return
     */
    public boolean canClick(long lastClickTime, int intervalTime) {
        long currentTime = System.currentTimeMillis();
        long realIntervalTime  = currentTime - lastClickTime;
//        Log.d(TAG, "canClick currentTime= " + currentTime + " lastClickTime= " + lastClickTime + " realIntervalTime= " + realIntervalTime);
        return realIntervalTime >= intervalTime;
    }
}
